import { AmbientLight, AxesHelper, BoxBufferGeometry, GridHelper, Mesh, MeshStandardMaterial, PerspectiveCamera, Scene, Vector3, WebGLRenderer,MOUSE, Object3D, Vector2, Raycaster } from "three";

import Stats from 'three/examples/jsm/libs/stats.module'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { TransformControls } from 'three/examples/jsm/controls/TransformControls'

export class TEngine {

    private dom: Element
    private renderer: WebGLRenderer
    private mouse: Vector2

    private raycaster: Raycaster

    private scene: Scene
    private camera: PerspectiveCamera
    private transformControls: TransformControls

    constructor(dom: HTMLElement) {
        this.dom = dom
        //渲染器对象
        const renderer = new WebGLRenderer({
            antialias:true //开启抗锯齿
        });
        renderer.shadowMap.enabled = true // 造成阴影效果
        console.log(dom);

        //场景
        const scene = new Scene()
        //相机
        this.camera = new PerspectiveCamera(45, dom.offsetWidth / dom.offsetHeight, 1, 1000)
        this.camera.position.set(250, 250, 250)
        this.camera.lookAt(new Vector3(0, 0, 0))
        this.camera.up = new Vector3(0, 1, 0)

        // this.renderer.domElement.width = dom.offsetWidth
        // this.renderer.domElement.hight = dom.offsetHeight
        renderer.setSize(dom.offsetWidth, dom.offsetHeight, true)

        // 初始性能监视器
        const stats = Stats()
        const statsDom = stats.domElement
        statsDom.style.position = 'fixed'
        statsDom.style.top = '0'
        statsDom.style.right = '5px'
        statsDom.style.left = 'unset'

        //初始orbitControls(轨道控制器)
        const orbitControls: OrbitControls = new OrbitControls(this.camera,renderer.domElement)
        // orbitControls.autoRotate = true //旋转
        // orbitControls.enableDamping = true; //开启惯性
        orbitControls.mouseButtons = {
            LEFT: null as unknown as MOUSE,
            MIDDLE: MOUSE.DOLLY,
            RIGHT:MOUSE.ROTATE
        }
        //初始变换控制器
        const transformControls = new TransformControls(this.camera,renderer.domElement)
        // const target = new Object3D()
        // transformControls.attach(target)
        // scene.add(target)
        scene.add(transformControls)

        //初始化射线发射器
        const raycaster = new Raycaster()

        //给renderer的对象添加鼠标事件
        const mouse = new Vector2()
        let x = 0
        let y = 0
        let width = 0
        let height = 0
        renderer.domElement.addEventListener('mousemove',(event)=>{
            // console.log(event.offsetX,event.offsetY); // 鼠标位置
            x = event.offsetX
            y = event.offsetY
            width = renderer.domElement.offsetWidth
            height = renderer.domElement.offsetHeight

            mouse.x = x/width*2-1
            mouse.y = -y*2/height+1
            // console.log(mouse.x,mouse.y); // 坐标转换
        })

        //
        renderer.domElement.addEventListener('click',event=>{
            raycaster.setFromCamera(mouse,this.camera)
            const intersection = raycaster.intersectObjects(scene.children)
            if(intersection.length){
                //console.log(intersection[0].object);
                const object = intersection[0].object
                transformControls.attach(object)
            }
        })
        // this.renderer.setClearColor('rgb(255,255,255)')
        // this.renderer.clearColor()
        //执行渲染操作   指定场景、相机作为参数
        // setInterval(()=>{
        //     console.log(1);
        //     this.renderer.render(this.scene, this.camera)
        // },1000/60)
        const renderFun = () => {
            // console.log(1);
            // box.position.x += -0.01 //平移沿x轴
            // box.rotation.y += 0.01 //旋转绕y轴
            // this.camera.position.x += -0.01 //相机跟随物体一起移动
            orbitControls.update()
            renderer.render(scene, this.camera)
            stats.update()
            requestAnimationFrame(renderFun)
        }
        renderFun()
        dom.appendChild(renderer.domElement)
        dom.appendChild(statsDom)

        this.renderer = renderer
        this.scene = scene
        this.transformControls = transformControls
        this.mouse = mouse
        this.raycaster = raycaster
    }

    addObject(...object: Object3D[]){
        object.forEach(elem => {
            this.scene.add(elem)
        })
    }

}